# create by fjrti@163.com
#
# support centos7/fedora/archlinux
# 
# TODO:
# 	download target
# 	qcow2 image
# 	telnet account @ alpine
#

fs ?= alpine
id ?= 0
net ?= user
kvm ?= on
cpu ?= 1
mem ?= 512m

LINUX = linux-6.6.106
# LINUX = linux-4.19.312
# LINUX = linux-3.10.108
BUSYBOX = busybox-1.33.1
CWD = $(shell pwd)
N = $(shell nproc)
GREEN = \033[0;32m
NC = \033[0m

ifeq ($(net),bridge)
netflag := tap,ifname=tap-toy-$(id),script=$(CWD)/qemu-ifup,downscript=$(CWD)/qemu-ifdown
else
port=$(shell expr $(id) + 23)
netflag := user,hostfwd=::$(port)-:23
endif

ifeq ($(kvm),on)
kvmflag := -enable-kvm
endif

help:
	@echo "Support targets:"
	@echo "  build      - Build linux kernel and rootfs"
	@echo "  create     - Create a qemu VM (root/123456)"
	@echo "  debug      - Debug linux kernel"
	@echo "  show       - List qemu VM"
	@echo "  stop       - Stop all qemu VM"
	@echo "  clean      - Delete kernel image and rootfs image"
	@echo "  distclean  - Delete all image and source code"
	@echo "* help       - Show this message, default target"
	@echo ""
	@echo "Support parameters:"
	@echo "  make id=0|1|..|9       [targets]  - Specify VM id (default 0)"
	@echo "  make fs=busybox|alpine [targets]  - Specify rootfs (default alpine)"
	@echo "  make net=user|bridge   [targets]  - Specify network mode (default user)"
	@echo "  make kvm=on|off        [targets]  - Specify kvm mode (default on)"
	@echo "  make cpu=size          [targets]  - Specify vcpu (default 1)"
	@echo "  make mem=size          [targets]  - Specify memory size (default 512m)"
	@echo ""

build: kernel.img $(fs).img
create: build
	@echo -e "$(GREEN)- stop vm (id=$(id))$(NC)"
	$(shell pkill -f vm-toy-$(id))
	@echo -e "$(GREEN)- start vm (id=$(id)) with network mode ($(net))$(NC)"
	qemu -name vm-toy-$(id) \
		-kernel kernel.img -initrd $(fs).img \
		-m $(mem) -smp $(cpu) $(kvmflag) \
		-append "root=/dev/ram rdinit=/sbin/init nokaslr selinux=0 audit=0 debug kgdboc=ttyS0,115200 kgdbwait" \
		-fsdev local,security_model=passthrough,id=fsdev0,path=/root/devel \
		-device virtio-9p-pci,id=fs0,fsdev=fsdev0,mount_tag=share \
		-net nic,model=virtio,macaddr=00:ff:ff:ff:ff:0$(id) \
		-net $(netflag) \
		-daemonize -vnc :$(id) \
		$(debugflag)
_prepare: 
	$(eval debugflag := -S -s)
debug: _prepare create
	cd $(LINUX); gdb -q -tui -ex "add-auto-load-safe-path $(PWD)" \
		-ex "file vmlinux" \
		-ex 'set arch i386:x86-64:intel' \
		-ex 'target remote localhost:1234' \
		-ex 'break do_init_module' \
		-ex 'continue' \
		-ex 'disconnect' \
		-ex 'set arch i386:x86-64' \
		-ex 'target remote :1234'
kernel.img: $(LINUX)/.config config
	make -C $(LINUX) bzImage -j$(N)
	cp $(LINUX)/arch/x86/boot/bzImage $@
$(fs).img: $(BUSYBOX)/.config $(CWD)/gen_initramfs_$(fs)
	$(CWD)/gen_initramfs_$(fs) $@
$(LINUX)/.config $(BUSYBOX)/.config:
	export LINUX=$(LINUX); export BUSYBOX=$(BUSYBOX); $(CWD)/get_source
stop:
	@echo -e "$(GREEN)- stop all vm and clear bridge$(NC)"
	$(shell pkill -f vm-toy)
	$(shell pkill -f dnsmasq-br-toy)
	$(shell ip link set br-toy down &> /dev/null)
	$(shell ip link delete br-toy &>/dev/null)
	@rm -f /var/run/dnsmasq-br-toy.leases
clean: stop
	@echo -e "$(GREEN)- delete kernel and rootfs image$(NC)"
	@rm -f *.img
distclean: clean
	@echo -e "$(GREEN)- delete all source$(NC)"
	@rm -rf linux-* busybox-* alpine-* .tmp* 
show:
	@ps aux | grep -Eo "[q]emu-system-x86.*" | sed 's/ -/\n\t-/g'
	@l=/var/run/dnsmasq-br-toy.leases && \
		[ -f $$l ] && echo $$l && awk '/ff:ff:ff/{print "\t"$$2,$$3}' $$l || true

.PHONY: build create show debug _prepare clean stop distclean help
